package com.hong.spring.aop.interceptor;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * @Auther: csh
 * @Date: 2020/7/14 17:05
 * @Description:切面类
 */
@Component
@Aspect
@Order(1)
public class TransferLogAdvice {
    /**
     *
     * 功能描述:切入点
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/7/14 18:25
     */
    @Pointcut("execution(* com.hong.spring.aop.service.impl.OrderServiceImpl.*(..))")
    public void pointcut1(){

    }
    /**
     *
     * 功能描述:切入点
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/7/14 18:26
     */
    @Pointcut("execution(* com.hong.spring.aop.service.impl.*ServiceImpl.*(..))")
    public void myPointcut(){

    }
    /**
     *
     * 功能描述:前置通知：在方法前面执行
     *
     * @param: 
     * @return: 
     * @auther: csh
     * @date: 2020/7/14 18:30
     */
    @Before(value = "pointcut1() || myPointcut()")
    public void beforeExecute(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        List <Object> args = Arrays.asList(joinPoint.getArgs());
        System.out.println(this.getClass().getSimpleName()+"前置通知方法"+methodName+"参数"+args);
    }
    /**
     *
     * 功能描述:后置通知：在方法后执行
     *
     * @param:
     * @return:
     * @auther: csh
     * @date: 2020/7/14 18:33
     */
    @After(value = "pointcut1()")
    public void afterExecute(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        List <Object> args = Arrays.asList(joinPoint.getArgs());
        System.out.println(this.getClass().getSimpleName()+"后置通知方法"+methodName+"参数"+args);
    }

    /**
     * 后置返回通知：在方法正常执行后执行的代码,可以获取到方法的返回值
     * @param joinPoint
     */
    @AfterReturning(value = "pointcut1()",
            returning="result")
    public void afterReturning(JoinPoint joinPoint, Object result){

        String methodName = joinPoint.getSignature().getName();
        System.out.println(this.getClass().getSimpleName()+ " 后置返回通知方法名称:"+methodName+" 返回值:"+result);
    }

    /**
     * 后置异常通知：在方法抛出异常之后执行,可以访问到异常信息,且可以指定出现特定异常信息时执行代码
     * @param joinPoint
     */
    @AfterThrowing(value = "pointcut1()",
            throwing="exception")
    public void afterThrowing(JoinPoint joinPoint, Exception exception){

        String methodName = joinPoint.getSignature().getName();
        System.out.println(this.getClass().getSimpleName()+ " 后置异常通知方法名称:"+methodName+" 异常:"+exception);
    }

    /**
     * 环绕通知, 围绕着方法执行
     */
    @Around(value = "pointcut1()")
    public Object around(ProceedingJoinPoint joinPoint){

        String methodName = joinPoint.getSignature().getName();
        System.out.println(this.getClass().getSimpleName()+ " 环绕通知:"+methodName+" 环绕通知开始");

        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println(this.getClass().getSimpleName()+ " 环绕通知:"+methodName+" 环绕通知结束");
        return result;
    }
}
